//
//  ToolImageScanViewController.m
//  BDD_TWO
//
//  Created by XTW on 2023/6/9.
//

#import "ToolImageScanViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "TScannerCamera.h"
#import "CustomAlertView.h"
#import <PhotosUI/PhotosUI.h>
#import "GPUImage.h"
#import "TIPDFCalculateManager.h"
#import "ToolImageScanResultController.h"

@implementation IPDFRectangleFeature

- (instancetype)initWithFeature:(IPDFRectangleFeature *)feature {
    if (self = [super init]) {
        self.topLeft = feature.topLeft;
        self.topRight = feature.topRight;
        self.bottomLeft = feature.bottomLeft;
        self.bottomRight = feature.bottomRight;
    }
    return self;
}

- (CGPoint)leftMiddle {
    return CGPointMake((_topLeft.x + _bottomLeft.x) / 2, (_topLeft.y + _bottomLeft.y) / 2);
}

- (CGPoint)topMiddle {
    return CGPointMake((_topLeft.x + _topRight.x) / 2, (_topLeft.y + _topRight.y) /2);
}

-(CGPoint)rightMiddle {
    return CGPointMake((_topRight.x + _bottomRight.x) /2, (_topRight.y + _bottomRight.y) /2);
}

- (CGPoint)bottomMiddle {
    return CGPointMake((_bottomLeft.x + _bottomRight.x) / 2, (_bottomLeft.y + _bottomRight.y) / 2);
}

- (NSString *)description {
    return  [NSString stringWithFormat:@"%@%@%@%@",
             NSStringFromCGPoint(self.topLeft),
             NSStringFromCGPoint(self.topRight),
             NSStringFromCGPoint(self.bottomLeft),
             NSStringFromCGPoint(self.bottomRight)];
}

@end

@interface ToolImageScanViewController ()<AVCaptureVideoDataOutputSampleBufferDelegate> {
    BOOL finishLoad;
    BOOL _isStopped;//停止
    BOOL _isCapturing;//正在拍照
    CGFloat _imageDedectionConfidence;
    CGFloat _errorDedectionConfidence;
    dispatch_queue_t _captureQueue;
}
@property (weak, nonatomic) IBOutlet UIView *bottomView;
@property (weak, nonatomic) IBOutlet UIButton *sureBtn;

@property (nonatomic, strong) NSTimer *borderDetectTimeKeeper;
@property (nonatomic, assign) BOOL enableBorderDetection;//默认YES
@property (nonatomic, assign) CGFloat lastRectangleArea;//上一个矩形的面积
@property (nonatomic,strong) CIRectangleFeature    *borderDetectLastRectangleFeature;
@property (nonatomic,strong) IPDFRectangleFeature   *realRectangleFeature; //处理后的矩形坐标

@end

@implementation ToolImageScanViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"扫描";
    [self addBackBtn];
    [self initView];
    _captureQueue = dispatch_get_main_queue();
    [self initialize];
    [self cameraAuthority];
    // Do any additional setup after loading the view from its nib.
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self start];
    [self.view.layer insertSublayer:[TScannerCamera sharedInstance].previewLayer atIndex:0];

}

- (void)initialize {
    [[TScannerCamera sharedInstance].dataOutput setSampleBufferDelegate:self queue:_captureQueue];
    //预览实时信息
    [TScannerCamera sharedInstance].previewLayer.frame = CGRectMake(0, IS_iPhoneX_Top + NavBarHeight, SCREEN_WIDTH_DEVICE, SCREEN_HEIGHT_DEVICE - IS_iPhoneX_Top - NavBarHeight - self.bottomView.frame.size.height);
}

- (BOOL)cameraAuthority {
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (authStatus == AVAuthorizationStatusDenied || authStatus == AVAuthorizationStatusRestricted) {
        [self showGoSetting:@"开启【相机权限】后，才能正常扫描：【设置】-【赏金侠】-【相机】开启"];
        return NO;
    }
    [self localImageAuthority];
    return YES;
}

- (void)localImageAuthority {
    if ([PHPhotoLibrary authorizationStatus] == 2) { // 已被拒绝，没有相册权限，将无法保存拍的照片
        [self showGoSetting:@"开启【相册权限】后，才能正常访问本地相册：【设置】-【赏金侠】-【相册】中允许访问相册"];
    }
}


- (void)showGoSetting:(NSString *)errorStr{
    CustomAlertView *alertView = [[CustomAlertView alloc] initItem:errorStr withButtons:[NSArray arrayWithObjects:@"放弃", @"去设置", nil]];
    alertView.SureHandle = ^{
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:^(BOOL success) {}];
    };
    alertView.CancelHandle = ^{
        [self goBackAction];
    };
    [alertView show];
}

// 开始
- (void)start {
    if ([TScannerCamera sharedInstance].captureDevice) {
        _isStopped = NO;
        _imageDedectionConfidence = 0.0;
        _errorDedectionConfidence = 0.0;
        [[TScannerCamera sharedInstance].overLayer removeFromSuperlayer];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.borderDetectTimeKeeper = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(openenBorderDetectFunction) userInfo:nil repeats:YES];
        });
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [[TScannerCamera sharedInstance].captureSession startRunning];
        });
    }
}
//停止
- (void)stop {
    if ([TScannerCamera sharedInstance].captureDevice) {
        _isStopped = YES;
        [[TScannerCamera sharedInstance].overLayer removeFromSuperlayer];
        [self.borderDetectTimeKeeper invalidate];
        self.borderDetectTimeKeeper = nil;
    }
}

- (void)openenBorderDetectFunction {
    self.enableBorderDetection = YES;
}

#pragma mark - 点击拍照
- (IBAction)takephotoPress {
    [self loadingHUDAlert];
    [self feedbackGeneror];
    self.sureBtn.userInteractionEnabled = NO;
    
    if (![TScannerCamera sharedInstance].captureDevice) {
        return;
    }
    [self captureImageWithCompletionHander:^(UIImage *t_image) {
        [self hideHudAlert];
        t_image = [self fixOrientation:t_image];
        NSInteger scale =  [UIScreen mainScreen].scale;
        CGFloat width = [TScannerCamera sharedInstance].previewLayer.frame.size.width;
        CGFloat height = [TScannerCamera sharedInstance].previewLayer.frame.size.height;
        CGSize size = CGSizeMake(width*scale, height*scale);
        t_image = [t_image sd_resizedImageWithSize:size scaleMode:(SDImageScaleModeAspectFill)];
        self.sureBtn.userInteractionEnabled = YES;
        ToolImageScanResultController *viewCon = [[ToolImageScanResultController alloc] initWithNibName:@"ToolImageScanResultController" bundle:nil];
        viewCon.image = t_image;
        [self.navigationController pushViewController:viewCon animated:YES];
    }];
}

- (void)captureImageWithCompletionHander:(void(^)(UIImage *image))completionHandler {
    if (_isCapturing) {return;}
    _isCapturing = YES;
    dispatch_suspend(_captureQueue);
    AVCaptureConnection *videoConnection = [[TScannerCamera sharedInstance].stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
    [[TScannerCamera sharedInstance].stillImageOutput  captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
        NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
        CIImage *enhancedImage = [[CIImage alloc] initWithData:imageData options:@{kCIImageColorSpace:[NSNull null]}];
        enhancedImage = [self filteredImageUsingContrastFiltersOnImage:enhancedImage];
        //翻转90度矫正
        enhancedImage = [self correctImage:enhancedImage];
        // 图片绘制
        UIImage *outputImage = [self drawImage:enhancedImage];
        //裁剪
//        outputImage = [self clipImage:outputImage];
        //滤镜处理
//        outputImage = [self imageByFilterGroup:outputImage];
        //回调
        dispatch_async(dispatch_get_main_queue(), ^ {
            self->_isCapturing = NO;
            dispatch_resume(self->_captureQueue);
            completionHandler(outputImage);
        });
    }];
}

- (CIImage *)filteredImageUsingContrastFiltersOnImage:(CIImage *)image {
    return [CIFilter filterWithName:@"CIColorControls" withInputParameters:@{@"inputContrast":@(1.0),kCIInputImageKey:image}].outputImage;
}

- (void)feedbackGeneror {
    if (@available(iOS 10.0, *)) {
        if (finishLoad) {
            UIImpactFeedbackGenerator *feedBackGenertor = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium];
            [feedBackGenertor impactOccurred];
        }
    } else {
        // Fallback on earlier versions
    }
}

//方向矫正
- (CIImage *)correctImage:(CIImage *)inputImage {
    CIFilter *transform = [CIFilter filterWithName:@"CIAffineTransform"];
    [transform setValue:inputImage forKey:kCIInputImageKey];
    NSValue *rotation = [NSValue valueWithCGAffineTransform:CGAffineTransformMakeRotation(-90 * (M_PI/180))];
    [transform setValue:rotation forKey:kCIInputTransformKey];
    return [transform outputImage];
}

//图片绘制
- (UIImage *)drawImage:(CIImage *)inputImage {
    static CIContext *ctx = nil;
    if (!ctx) {
        ctx = [CIContext contextWithOptions:@{kCIContextWorkingColorSpace:[NSNull null]}];
    }
    CGSize bounds = inputImage.extent.size;
    
    static int bytesPerPixel = 8;
    uint rowBytes = bytesPerPixel * floorf(bounds.width);
    uint totalBytes = rowBytes * floorf(bounds.height);
    uint8_t *byteBuffer = malloc(totalBytes);
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    [ctx render:inputImage toBitmap:byteBuffer rowBytes:rowBytes bounds:inputImage.extent format:kCIFormatRGBA8 colorSpace:colorSpace];
    
    CGContextRef bitmapContext = CGBitmapContextCreate(byteBuffer,bounds.width,bounds.height,bytesPerPixel,rowBytes,colorSpace,kCGImageAlphaNoneSkipLast);
    CGImageRef imgRef = CGBitmapContextCreateImage(bitmapContext);
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(bitmapContext);
    free(byteBuffer);
    
    UIImage *outputImage = [UIImage imageWithCGImage:imgRef];
    CFRelease(imgRef);
    
    return outputImage;
}


//裁剪image
- (UIImage *)cutImage:(UIImage *)srcImg {
    //注意：这个rect是指横屏时的rect，即屏幕对着自己，home建在右边
    CGRect rect = CGRectMake((srcImg.size.height / CGRectGetHeight(self.view.frame)) * 70, 0, srcImg.size.width * 1.33, srcImg.size.width);
    CGImageRef subImageRef = CGImageCreateWithImageInRect(srcImg.CGImage, rect);
    CGFloat subWidth = CGImageGetWidth(subImageRef);
    CGFloat subHeight = CGImageGetHeight(subImageRef);
    CGRect smallBounds = CGRectMake(0, 0, subWidth, subHeight);
    //旋转后，画出来
    CGAffineTransform transform = CGAffineTransformIdentity;
    transform = CGAffineTransformTranslate(transform, 0, subWidth);
    transform = CGAffineTransformRotate(transform, -M_PI_2);
    CGContextRef ctx = CGBitmapContextCreate(NULL, subHeight, subWidth,
                                             CGImageGetBitsPerComponent(subImageRef), 0,
                                             CGImageGetColorSpace(subImageRef),
                                             CGImageGetBitmapInfo(subImageRef));
    CGContextConcatCTM(ctx, transform);
    CGContextDrawImage(ctx, smallBounds, subImageRef);
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    
    CGImageRelease(subImageRef);
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}

//旋转image
- (UIImage *)fixOrientation:(UIImage *)srcImg {
    CGAffineTransform transform = CGAffineTransformIdentity;
    CGFloat width = srcImg.size.width;
    CGFloat height = srcImg.size.height;
    
    CGContextRef ctx;
    
    switch ([[UIDevice currentDevice] orientation]) {
        case UIDeviceOrientationUnknown:
        case UIDeviceOrientationFaceUp:
        case UIDeviceOrientationFaceDown:
        case UIDeviceOrientationPortrait:
        case UIDeviceOrientationPortraitUpsideDown: //竖屏，不旋转
            ctx = CGBitmapContextCreate(NULL, width, height,
                                        CGImageGetBitsPerComponent(srcImg.CGImage), 0,
                                        CGImageGetColorSpace(srcImg.CGImage),
                                        CGImageGetBitmapInfo(srcImg.CGImage));
            break;
            
        case UIDeviceOrientationLandscapeLeft:  //横屏，home键在右手边，逆时针旋转90°
            transform = CGAffineTransformTranslate(transform, height, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            ctx = CGBitmapContextCreate(NULL, height, width,
                                        CGImageGetBitsPerComponent(srcImg.CGImage), 0,
                                        CGImageGetColorSpace(srcImg.CGImage),
                                        CGImageGetBitmapInfo(srcImg.CGImage));
            break;
            
        case UIDeviceOrientationLandscapeRight:  //横屏，home键在左手边，顺时针旋转90°
            transform = CGAffineTransformTranslate(transform, 0, width);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            ctx = CGBitmapContextCreate(NULL, height, width,
                                        CGImageGetBitsPerComponent(srcImg.CGImage), 0,
                                        CGImageGetColorSpace(srcImg.CGImage),
                                        CGImageGetBitmapInfo(srcImg.CGImage));
            break;
            
        default:
            break;
    }
    
    CGContextConcatCTM(ctx, transform);
    CGContextDrawImage(ctx, CGRectMake(0,0,width,height), srcImg.CGImage);
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    
    return img;
}

- (void)initView {
    [self.bottomView setFrame:CGRectMake(0, SCREEN_HEIGHT_DEVICE - 70 - IS_iPhoneX_Bottom, SCREEN_WIDTH_DEVICE, 70 + IS_iPhoneX_Bottom)];
   
}

#pragma mark ======= AVCaptureVideoDataOutputSampleBufferDelegate ======
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    if (_isStopped  || _isCapturing || !CMSampleBufferIsValid(sampleBuffer)) return;
    CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
    CIImage *image = [CIImage imageWithCVPixelBuffer:pixelBuffer];
    if (self.enableBorderDetection) {
        self.enableBorderDetection = NO;
        image = [CIImage imageWithCGImage: [self imageByContrastFilter:[self drawImage:image]].CGImage];//滤镜处理  消耗cpu 但是快
//        image = [self filteredImageUsingContrastFiltersOnImage:image];
        dispatch_async(dispatch_get_main_queue(), ^{
            
            [[TScannerCamera sharedInstance].overLayer  removeFromSuperlayer];
            
            CIDetector *detector = [self highAccuracyRectangleDetector];
            NSArray *features = [detector featuresInImage:image];
            if (features.count) {
                CGFloat area = [TIPDFCalculateManager areaOfTheQuadrilateral:features.firstObject];
                CGFloat difference = fabs(self.lastRectangleArea - area);
                CGFloat errorValue = fabs(self.lastRectangleArea * 0.05);//误差5%
                self.lastRectangleArea = area;

                if (difference < errorValue) {
                    self->_imageDedectionConfidence += 0.5;
                }
                if (self->_imageDedectionConfidence > 10 && difference > errorValue*3) {//误差15%
                    self->_errorDedectionConfidence += 0.5;//不显示
                } else {
                    self.lastRectangleArea = area;
                    self.borderDetectLastRectangleFeature = features.firstObject;
                    self.realRectangleFeature = [self coordinateTransformationForRectangleFeature:self.borderDetectLastRectangleFeature ciImage:image];
                    CAShapeLayer *overLayer = [self drawHighlightOverlayForRectangleFeature:self.realRectangleFeature];
                    [[TScannerCamera sharedInstance].previewLayer addSublayer:overLayer];
                    [TScannerCamera sharedInstance].overLayer = overLayer;
                    if (self->_errorDedectionConfidence > 5) {
                        self->_imageDedectionConfidence = 0;
                        self->_errorDedectionConfidence = 0;
                    }
                }
            } else {
                self->_imageDedectionConfidence = 0.0f;
                self->_errorDedectionConfidence = 0;
            }
        });
    }
}

- (UIImage *)imageByContrastFilter:(UIImage *)image {
    //对比度 (0 - 4)
    GPUImageContrastFilter *contrastFilter = [[GPUImageContrastFilter alloc] init];
    contrastFilter.contrast = 4;
    return [contrastFilter imageByFilteringImage:image];
}

//高精度矩形探测器
- (CIDetector *)highAccuracyRectangleDetector {
    static CIDetector *detector = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^ {
        detector = [CIDetector detectorOfType:CIDetectorTypeRectangle
                                      context:nil
                                      options:@{CIDetectorAccuracy : CIDetectorAccuracyHigh,
                                                CIDetectorImageOrientation:@(0),
                                                }];
    });
    return detector;
}


// 坐标仿射变换 - 绘制遮罩层
- (IPDFRectangleFeature *)coordinateTransformationForRectangleFeature:(CIRectangleFeature *)feature ciImage:(CIImage *)image {
    CGSize imageSize = image.extent.size;
    CGSize contentSize = CGSizeMake(SCREEN_WIDTH_DEVICE, SCREEN_HEIGHT_DEVICE - IS_iPhoneX_Top - NavBarHeight - self.bottomView.frame.size.height);
    CGFloat scale = MIN(imageSize.width / contentSize.width, imageSize.height / contentSize.height);
    //scale
    CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformIdentity, 1/scale, 1/scale);
    CGPoint topLeft = CGPointApplyAffineTransform(feature.topLeft, transform);
    CGPoint topRight = CGPointApplyAffineTransform(feature.topRight, transform);
    CGPoint bottomLeft = CGPointApplyAffineTransform(feature.bottomLeft, transform);
    CGPoint bottomRight = CGPointApplyAffineTransform(feature.bottomRight, transform);
    
    //rotate coordinate-Y + offset
    CGFloat off_x = (contentSize.width - imageSize.width / scale) / 2;
    CGFloat off_y = (contentSize.height - imageSize.height / scale) / 2;
    
    topLeft = CGPointMake(topLeft.x + off_x, contentSize.height - topLeft.y - off_y);
    topRight = CGPointMake(topRight.x + off_x, contentSize.height - topRight.y - off_y);
    bottomRight = CGPointMake(bottomRight.x + off_x, contentSize.height - bottomRight.y - off_y);
    bottomLeft = CGPointMake(bottomLeft.x + off_x, contentSize.height - bottomLeft.y - off_y);
    
    IPDFRectangleFeature *transformFeature = [[IPDFRectangleFeature alloc] init];
    transformFeature.topLeft = topLeft;
    transformFeature.topRight = topRight;
    transformFeature.bottomLeft = bottomLeft;
    transformFeature.bottomRight = bottomRight;
    
    return transformFeature;
}


// 绘制边缘检测高亮层
- (CAShapeLayer *)drawHighlightOverlayForRectangleFeature:(IPDFRectangleFeature *)feature {
    UIColor *layerColor;
    UIColor *borderColor;
//    if (_imageDedectionConfidence > 10) {
//        layerColor = [UIColor colorWithRed:0.0 green:1 blue:0.0 alpha:0.3];
//        borderColor = [UIColor colorWithRed:0.0 green:1 blue:0 alpha:1.0];
//    } else {
        layerColor = [UIColor colorWithRed:57.0/255 green:119.0/255 blue:255.0/255 alpha:0.3];
        borderColor = ThemeColor;
//    }
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:feature.topLeft];
    [path addLineToPoint:feature.topRight];
    [path addLineToPoint:feature.bottomRight];
    [path addLineToPoint:feature.bottomLeft];
    [path addLineToPoint:feature.topLeft];
    
    
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = path.CGPath;
    shapeLayer.frame = CGRectMake(0, 0, SCREEN_WIDTH_DEVICE, SCREEN_HEIGHT_DEVICE - IS_iPhoneX_Top - NavBarHeight - self.bottomView.frame.size.height);
    shapeLayer.fillColor = layerColor.CGColor;
    shapeLayer.strokeColor = borderColor.CGColor;
    
    
    return shapeLayer;
}

@end
